<template>
  <div class="cge4-region-comp">
    <div class="title-box">{{ config.title }}</div>

    <div class="cge4-region-comp-content">
      <div ref="barWrapperEl" class="bar-wrapper">
        <div
          class="bar-box zhejiang-bar-box"
          style="height: 110px; width: 80px;"
        ></div>
        <div
          class="bar-box shanghai-bar-box"
          style="height: 110px; width: 80px;"
        ></div>
        <div
          class="bar-box anhui-bar-box"
          style="height: 110px; width: 80px;"
        ></div>
        <div
          class="bar-box jiangsu-bar-box"
          style="height: 110px; width: 80px;"
        ></div>
      </div>

      <svg class="path-svg" viewBox="0 0 1816 1508">
        <circle
          class="point-jiangsu"
          cx="1000"
          cy="200"
          r="10"
          fill="#fdd"
          stroke="none"
        ></circle>
        <circle
          class="point-anhui"
          cx="400"
          cy="600"
          r="10"
          fill="#fdd"
          stroke="none"
        ></circle>
        <circle
          class="point-zhejiang"
          cx="1000"
          cy="1000"
          r="10"
          fill="#fdd"
          stroke="none"
        ></circle>
        <circle
          class="point-shanghai"
          cx="1530"
          cy="700"
          r="10"
          fill="#fdd"
          stroke="none"
        ></circle>
        <!-- line arrow -->
        <path
          d="M1428.6224647862243,343.9468635644531 L1439.7335647862244,319.50241356445315 L1450.8446547862243,343.9468635644531 C1443.4372547862245,343.9468635644531 1436.0298647862244,343.9468635644531 1428.6224647862243,343.9468635644531 z"
          fill="#fff"
          transform="rotate(-48.2374 1439.73 331.725)"
        ></path>
        <path
          d="M520.604751328125,298.946001113739 L531.715851328125,274.501551113739 L542.826941328125,298.946001113739 C535.419541328125,298.946001113739 528.012151328125,298.946001113739 520.604751328125,298.946001113739 z"
          fill="#fff"
          transform="rotate(-138.253 531.716 286.724)"
        ></path>
        <path
          d="M 611.60652 307.9461705960464 L 622.71762 283.5017205960463 L 633.82871 307.9461705960465 C 626.42131 307.9461705960464 619.01392 307.9461705960464 611.60652 307.9461705960464 z"
          fill="#fff"
          transform="rotate(53.4965 622.718 295.724)"
        ></path>
        <path
          d="M758.6093924670411,418.9483396090698 L769.720492467041,394.5038896090698 L780.831582467041,418.9483396090698 C773.424182467041,418.9483396090698 766.016792467041,418.9483396090698 758.6093924670411,418.9483396090698 z"
          fill="#fff"
          transform="rotate(67.2619 769.72 406.726)"
        ></path>
        <path
          transform="rotate(133.461 1402.73 393.726)"
          d="M1391.6217217002868,405.948083196106 L1402.7328217002869,381.50363319610597 L1413.8439117002868,405.948083196106 C1406.436511700287,405.948083196106 1399.0291217002869,405.948083196106 1391.6217217002868,405.948083196106 z"
          fill="#fff"
        ></path>
        <path
          transform="rotate(-121.016 1226.73 778.733)"
          d="M1215.6182845993042,790.9555996287537 L1226.7293845993042,766.5111496287536 L1237.8404745993041,790.9555996287537 C1230.4330745993043,790.9555996287537 1223.0256845993042,790.9555996287537 1215.6182845993042,790.9555996287537 z"
          fill="#fff"
        ></path>
        <path
          transform="rotate(60.9247 1160.73 738.733)"
          d="M1149.6170016369629,750.9548207423401 L1160.728101636963,726.5103707423401 L1171.8391916369628,750.9548207423401 C1164.4317916369628,750.9548207423401 1157.024401636963,750.9548207423401 1149.6170016369629,750.9548207423401 z"
          fill="#fff"
        ></path>
        <path
          transform="rotate(136.591 864.722 656.731)"
          d="M853.6112336669921,668.9532206396484 L864.7223336669922,644.5087706396484 L875.8334236669921,668.9532206396484 C868.4260236669923,668.9532206396484 861.0186336669922,668.9532206396484 853.6112336669921,668.9532206396484 z"
          fill="#fff"
        ></path>
        <path
          transform="rotate(-43.2234 820.721 709.732)"
          d="M809.6103965145874,721.9542430963135 L820.7214965145874,697.5097930963135 L831.8325865145873,721.9542430963135 C824.4251865145875,721.9542430963135 817.0177965145874,721.9542430963135 809.6103965145874,721.9542430963135 z"
          fill="#fff"
        ></path>
        <path
          transform="rotate(177.293 1049.73 488.728)"
          d="M1038.614848302307,500.949939100647 L1049.7259483023072,476.50548910064697 L1060.837038302307,500.949939100647 C1053.429638302307,500.949939100647 1046.0222483023072,500.949939100647 1038.614848302307,500.949939100647 z"
          fill="#fff"
        ></path>
        <path
          transform="rotate(6.32854 951.724 486.728)"
          d="M940.6129433018493,498.9498957719421 L951.7240433018494,474.50544577194216 L962.8351333018493,498.9498957719421 C955.4277333018495,498.9498957719421 948.0203433018494,498.9498957719421 940.6129433018493,498.9498957719421 z"
          fill="#fff"
        ></path>
        <path
          transform="rotate(-87.2963 1003.72 572.729)"
          d="M992.6139600073243,585.9515939367675 L1003.7250600073244,561.5071439367675 L1014.8361500073242,585.9515939367675 C1007.4287500073242,585.9515939367675 1000.0213600073243,585.9515939367675 992.6139600073243,585.9515939367675 z"
          fill="#fff"
        ></path>
        <!-- line -->
        <path
          data-prov="jiangsu2anhui"
          class="province-path jiangsu2anhui"
          d="M1000 200 Q 500 50 400 600"
          stroke="#fff"
          fill="transparent"
          stroke-width="3"
        ></path>
        <path
          data-prov="anhui2jiangsu"
          class="province-path anhui2jiangsu"
          d="M400 600 Q 600 150 1000 200"
          stroke="#fff"
          fill="transparent"
          stroke-width="3"
        ></path>
        <path
          data-prov="anhui2zhejiang"
          class="province-path anhui2zhejiang"
          d="M400 600 Q 900 400 1000 1000"
          stroke="#fff"
          fill="transparent"
          stroke-width="3"
        ></path>
        <path
          data-prov="zhejiang2anhui"
          class="province-path zhejiang2anhui"
          d="M1000 1000 Q 800 500 400 600"
          stroke="#fff"
          fill="transparent"
          stroke-width="3"
        ></path>
        <path
          data-prov="zhejiang2shanghai"
          class="province-path zhejiang2shanghai"
          d="M1000 1000 Q 1100 600 1530 700"
          stroke="#fff"
          fill="transparent"
          stroke-width="3"
        ></path>
        <path
          data-prov="shanghai2zhejiang"
          class="province-path shanghai2zhejiang"
          d="M1530 700 Q 1200 700 1000 1000"
          stroke="#fff"
          fill="transparent"
          stroke-width="3"
        ></path>
        <path
          data-prov="shanghai2jiangsu"
          class="province-path shanghai2jiangsu"
          d="M1530 700 Q 1600 200 1000 200"
          stroke="#fff"
          fill="transparent"
          stroke-width="3"
        ></path>
        <path
          data-prov="jiangsu2shanghai"
          class="province-path jiangsu2shanghai"
          d="M1000 200 Q 1500 300 1530 700"
          stroke="#fff"
          fill="transparent"
          stroke-width="3"
        ></path>
        <path
          data-prov="anhui2shanghai"
          class="province-path anhui2shanghai"
          d="M400 600 Q 1100 100 1530 700"
          stroke="#fff"
          fill="transparent"
          stroke-width="3"
        ></path>
        <path
          data-prov="shanghai2anhui"
          class="province-path shanghai2anhui"
          d="M1530 700 Q 1100 500 400 600"
          stroke="#fff"
          fill="transparent"
          stroke-width="3"
        ></path>
        <path
          data-prov="jiangsu2zhejiang"
          class="province-path jiangsu2zhejiang"
          d="M1000 200 Q 1100 500 1000 1000"
          stroke="#fff"
          fill="transparent"
          stroke-width="3"
        ></path>
        <path
          data-prov="zhejiang2jiangsu"
          class="province-path zhejiang2jiangsu"
          d="M1000 1000 Q 900 500 1000 200"
          stroke="#fff"
          fill="transparent"
          stroke-width="3"
        ></path>
      </svg>

      <div ref="tooltip" class="tooltip">
        {{ tooltipData.label }}: &nbsp;{{
          tooltipData.content.includes('-') ? '' : '+'
        }}{{ tooltipData.content }}%
      </div>

      <div class="legend-box" :class="{ dark: theme === 'nebula-dark' }">
        <div class="legend-item">
          <span
            class="legend-color"
            :style="{ backgroundColor: barChartColors[0] }"
          ></span
          ><span>实际GDP（亿元）</span>
        </div>
        <div class="legend-item">
          <span
            class="legend-color"
            :style="{ backgroundColor: barChartColors[1] }"
          ></span
          ><span>模拟GDP（亿元）</span>
        </div>
      </div>
    </div>
  </div>
</template>

<script lang="ts">
import { Component, Vue, Prop, Watch } from 'vue-property-decorator'
import { DiffBarChart } from '@zjlabvis/vis-charts'
import { isEqual, throttle } from 'lodash'
import Big from 'big.js'

const nameMapping: any = {
  zhejiang: '浙江GDP（亿元）',
  shanghai: '上海GDP（亿元）',
  anhui: '安徽GDP（亿元）',
  jiangsu: '江苏GDP（亿元）',
  prov_zhejiang: '浙江省',
  prov_shanghai: '上海市',
  prov_anhui: '安徽省',
  prov_jiangsu: '江苏省',
  jiangsu2anhui: '省际调出_江苏省_安徽省',
  anhui2jiangsu: '省际调入_安徽省_江苏省',
  anhui2zhejiang: '省际调出_安徽省_浙江省',
  zhejiang2anhui: '省际调入_浙江省_安徽省',
  zhejiang2shanghai: '省际调入_浙江省_上海市',
  shanghai2zhejiang: '省际调出_上海市_浙江省',
  shanghai2jiangsu: '省际调入_上海市_江苏省',
  jiangsu2shanghai: '省际调出_江苏省_上海市',
  anhui2shanghai: '省际调出_安徽省_上海市',
  shanghai2anhui: '省际调入_上海市_安徽省',
  jiangsu2zhejiang: '省际调出_江苏省_浙江省',
  zhejiang2jiangsu: '省际调入_浙江省_江苏省',
}

@Component
export default class Cge4RegionComp extends Vue {
  @Prop() config!: any
  @Prop() theme!: 'nebula-white' | 'nebula-dark'

  private zhejiangBarValue: any[] = []
  private shanghaiBarValue: any[] = []
  private anhuiBarValue: any[] = []
  private jiangsuBarValue: any[] = []
  private barChartInstance: any[] = []
  private resizeObserver: any
  private tooltipData = {
    label: '',
    content: '',
  }
  private barChartColors = ['#FBC94B', '#737CF6']

  mounted() {
    if (this.config.value) {
      this.parseValue()
      this.initResizeObserver()
    }
  }

  @Watch('config.value', { immediate: true })
  private onValueChange(
    newValue: any[] | undefined,
    oldValue: any[] | undefined
  ) {
    if (!this.$el) {
      return
    }
    if (newValue && !isEqual(newValue, oldValue)) {
      this.parseValue()
    }
  }

  private parseValue() {
    const { value } = this.config
    // const value = demoData
    ;['zhejiang', 'shanghai', 'anhui', 'jiangsu'].forEach((key: string) => {
      // @ts-ignore
      this[`${key}BarValue`] = value.map((v: any) => ({
        类别: v.类别,
        [nameMapping[key]]: v[nameMapping[key]],
      }))
    })

    this.renderBarChart()
    this.adjustPosition()
  }

  /**
   * 渲染barchart
   */
  private renderBarChart() {
    this.barChartInstance.forEach((instance) => {
      instance.destroy()
    })
    ;['zhejiang', 'shanghai', 'anhui', 'jiangsu'].forEach((key, index) => {
      // 在当前容器里寻找

      const config: any = {
        title: '',
        titleIsShow: false,
        // animation: true,
        animation: {
          // 配置图表第一次加载时的入场动画
          appear: {
            // animation: 'wave-in', // 动画效果
            duration: 3000, // 动画执行时间
          },
        },
        labelKey: '类别',
        columnWidthRatio: 0.8,
        valueKey: nameMapping[key],
        xAxisGridIsShow: false,
        yAxisGridIsShow: false,
        legendIsShow: false,
        labelIsShow: false,
        padding: [0, 0, 0, 0],
        size: [80, 120],
        maxColumnWidth: 35,
        xAxis: {
          label: null,
        },
        yAxis: {
          tickCount: 0,
        },

        tooltip: {
          formatter: (data: any) => {
            const value = new Big(data[nameMapping[key]]).toFixed(2)
            return {
              name: data.diffField,
              value,
            }
          },
        },
        colors: ['#CC69D9', '#0F0', '#00F'],
        // @ts-ignore
        value: this[`${key}BarValue`],
        diffValuePrecision: this.config.diffValuePrecision || 1,
      }

      config.colors = {
        实际值: this.barChartColors[0],
        模拟值: this.barChartColors[1],
      }
      config.colorsField = config.labelKey
      this.barChartInstance[index] = new DiffBarChart(
        this.$el.querySelector(`.${key}-bar-box`) as HTMLElement,
        config
      )
    })
  }

  /**
   * 根据背景图片宽高比例以及元素宽高情况调整 bar-box 的位置
   */
  private adjustPosition() {
    const bgImgWHRatio = 1816 / 1508 // 背景图片宽高比
    const { width, height } = this.$el.getBoundingClientRect()
    const currentElementRatio = width / height
    if (!this.$refs.barWrapperEl) {
      return
    }
    const $barWrapper = this.$refs.barWrapperEl as HTMLElement
    if (currentElementRatio > bgImgWHRatio) {
      $barWrapper.style.height = '100%'
      $barWrapper.style.width = `${height * bgImgWHRatio}px`
    } else {
      $barWrapper.style.width = '100%'
      $barWrapper.style.height = `${width / bgImgWHRatio}px`
    }
  }

  initResizeObserver() {
    // @ts-ignore
    if (!window.ResizeObserver) {
      return
    }
    const throttleResize = throttle(this.adjustPosition, 300)
    // @ts-ignore
    this.resizeObserver = new ResizeObserver(() => {
      throttleResize()
    })
    this.resizeObserver.observe(this.$el)
  }

  initTooltip() {
    const svgElement = this.$el.querySelector('.path-svg')
    if (!svgElement) {
      return
    }
    svgElement.querySelectorAll('.province-path').forEach((target) => {
      target.addEventListener('mousemove', this.onMouseMove)
      target.addEventListener('mouseout', this.onMouseOut)
    })
  }

  private onMouseMove(event: any) {
    // @ts-ignore
    const info = event?.target?.getAttribute('data-prov')
    const mappingValue = nameMapping[info]
    if (mappingValue) {
      const currentValue = this.config.value.filter(
        (v: any) => v['类别'] === '实际值'
      )[0][mappingValue]
      const targetValue = this.config.value.filter(
        (v: any) => v['类别'] === '模拟值'
      )[0][mappingValue]
      const bigValue = new Big(targetValue)
      this.tooltipData = {
        label: mappingValue,
        content: bigValue
          .minus(currentValue)
          .times(100)
          .div(currentValue)
          .toFixed(2),
      }
      const targetElement = this.$refs.tooltip as HTMLElement
      const { x, y } = this.$el.getBoundingClientRect()
      targetElement.style.display = 'block'
      targetElement.style.top = `${event.pageY - y + 10}px`
      targetElement.style.left = `${event.pageX - x + 10}px`
    }
  }

  private onMouseOut() {
    const targetElement = this.$refs.tooltip as HTMLElement
    targetElement.style.display = 'none'
  }

  private destroyTooltip() {
    const svgElement = this.$el.querySelector('.path-svg')
    if (!svgElement) {
      return
    }
    svgElement.querySelectorAll('.province-path').forEach((target) => {
      target.removeEventListener('mousemove', this.onMouseMove)
      target.removeEventListener('mouseout', this.onMouseOut)
    })
  }

  beforeDestroy() {
    this.resizeObserver.disconnect()
    this.resizeObserver = null
    this.destroyTooltip()
  }
}
</script>

<style lang="less" scoped>
.cge4-region-comp {
  height: 100%;
  margin-top: 10px;

  .cge4-region-comp-content {
    align-items: center;
    background: url('../../assets/CGE4Region-bg.png') no-repeat center;
    background-size: contain;
    display: flex;
    height: calc(100% - 38px);
    position: relative;
  }

  .title-box {
    color: var(--title-color);
    font-size: 14px;
    font-weight: 500;
    font-weight: 600;
    height: 38px;
    letter-spacing: 1px;
    line-height: 38px;
    overflow: hidden;
    padding: 0 16px;
    padding-right: 55px;
    text-overflow: ellipsis;
    white-space: nowrap;
    width: 100%;
  }

  .bar-wrapper {
    margin: 0 auto;
    pointer-events: none;
    position: relative;
    z-index: 9;
  }

  .bar-box {
    height: 200px;
    pointer-events: auto;
    position: absolute;
    width: 200px;

    /deep/ .g2-tooltip {
      min-width: 180px;
    }

    /deep/ .g2-tooltip-value {
      margin-left: 10px !important;
    }

    /deep/ .chart-title {
      height: 0;
    }
  }

  .zhejiang-bar-box {
    left: 65%;
    top: 55%;
  }

  .shanghai-bar-box {
    left: 71%;
    top: 30%;
  }

  .jiangsu-bar-box {
    left: 62%;
    top: 10%;
  }

  .anhui-bar-box {
    left: 25%;
    top: 22%;
  }

  .path-svg {
    height: 100%;
    left: 0;
    position: absolute;
    top: 0;
    width: 100%;
  }

  .tooltip {
    background-color: rgba(255, 255, 255, 0.8);
    background-color: rgb(255, 255, 255);
    border-radius: 3px;
    box-shadow: rgb(174 174 174) 0 0 10px;
    color: rgb(89, 89, 89);
    display: none;
    padding: 8px 15px;
    position: absolute;
    z-index: 99;
  }

  .legend-box {
    bottom: 12%;
    left: 5%;
    position: absolute;

    &.dark {
      color: #fff;
    }

    .legend-item {
      margin-top: 8px;
    }

    /* stylelint-disable  */
    .legend-color {
      border: none;
      display: inline-block;
      height: 16px;
      margin-bottom: -2px;
      margin-right: 12px;
      width: 16px;
    }
    /* stylelint-enable  */
  }

  .province-path {
    animation: pathMove 1s linear reverse infinite;
    stroke-dasharray: 30px, 10px;
  }

  @keyframes pathMove {
    0% {
      stroke-dashoffset: 0;
    }

    100% {
      stroke-dashoffset: 40px;
    }
  }
}
</style>
